package com.migo.thread;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.OSSObject;
import com.migo.oss.OSSFactory;
import com.migo.utils.FileMD5Util;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;
import java.util.zip.Adler32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * Created by Wes on 2018/12/5.
 */
public class FirmwareZipThread implements Runnable {

    private String path;
    private String keys;
    private String fileName;
    private OSSFactory ossFactory;
    private StringRedisTemplate redisTemplate;
    private String md5key;

    public FirmwareZipThread(String path, String keys, String fileName, OSSFactory ossFactory,StringRedisTemplate redisTemplate,String md5key) {
        this.redisTemplate = redisTemplate;
        this.md5key = md5key;
        this.path = path;
        this.keys = keys;
        this.fileName = fileName;
        this.ossFactory = ossFactory;
    }

    @Override
    public void run() {
        // endpoint以杭州为例，其它region请按实际情况填写
        String endpoint = "http://oss-cn-hongkong.aliyuncs.com";
        // 云账号AccessKey有所有API访问权限，建议遵循阿里云安全最佳实践，创建并使用RAM子账号进行API访问或日常运维，请登录 https://ram.console.aliyun.com 创建
        String accessKeyId = "LTAI1f1IvJ4gaW1Y";
        String accessKeySecret = "utIEW0SCOvMSHBuG1DO8S9goVWbP41";
        String bucketName = "gcsbucket";
        try {
            // 初始化
            OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
            ;
            // 创建临时文件
            File zipFile = File.createTempFile(this.fileName, ".zip");
            FileOutputStream f = new FileOutputStream(zipFile);
            /**
             * 作用是为任何OutputStream产生校验和
             * 第一个参数是制定产生校验和的输出流，第二个参数是指定Checksum的类型 （Adler32（较快）和CRC32两种）
             */
            CheckedOutputStream csum = new CheckedOutputStream(f, new Adler32());
            // 用于将数据压缩成Zip文件格式
            ZipOutputStream zos = new ZipOutputStream(csum);

            String[] keylist = this.keys.split(",");
            for (String ossfile : keylist) {
                // 获取Object，返回结果为OSSObject对象
                OSSObject ossObject = ossClient.getObject(bucketName, ossfile);
                // 读去Object内容  返回
                InputStream inputStream = ossObject.getObjectContent();
                // 对于每一个要被存放到压缩包的文件，都必须调用ZipOutputStream对象的putNextEntry()方法，确保压缩包里面文件不同名
                zos.putNextEntry(new ZipEntry(ossfile.split("/")[2]));
                int bytesRead = 0;
                // 向压缩文件中输出数据
                while ((bytesRead = inputStream.read()) != -1) {
                    zos.write(bytesRead);
                }
                inputStream.close();
                zos.closeEntry(); // 当前文件写完，定位为写入下一条项目
            }
            zos.close();
            FileInputStream fis = new FileInputStream(zipFile);
            //生成md5 val 存储redis 两天
            String val = FileMD5Util.getFileMD5(zipFile);
            redisTemplate.boundValueOps(this.md5key).set(val);
            redisTemplate.boundValueOps(this.md5key).expire(2, TimeUnit.DAYS);
//            ossClient.putObject(bucketName, this.path+".zip",fis);//原生上传
            ossClient.shutdown();
            this.ossFactory.build().upload(fis, this.path+".zip"); //配置上传
            // 删除临时文件
            zipFile.delete();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
